#include <string.h>
#include <iostream>

using namespace std;

class String{
public:
    String()
        :_size(0)
    {
        memset(_buffer._arr,0,sizeof(_buffer._arr));
    }
    String(const char *pstr)
        :_size(strlen(pstr))
    {
        if(_size < 16){
            memset(_buffer._arr,0,sizeof(_buffer._arr));
            strcpy(_buffer._arr,pstr);
            //这里是把pstr指针所指向的内容拷贝到_buffer._arr数组中
        }else{
            _buffer._pstr = new char [strlen(pstr)+1]();
            // _buffer._pstr = new char [_size+1]();
            strcpy(_buffer._pstr,pstr);
        }
    }
    //拷贝构造函数
    String(const String &rhs)
        :_size(rhs._size)
    {
        if(_size < 16){
            memset(_buffer._arr,0,sizeof(_buffer._arr));
            strcpy(_buffer._arr,rhs._buffer._arr);
        }else{
            _buffer._pstr = new char [strlen(rhs._buffer._pstr)+1]();
            strcpy(_buffer._pstr,rhs._buffer._pstr);
        }
    }
    //析构函数
    ~String(){
        if(_size > 15){
            delete [] _buffer._pstr;
            _buffer._pstr = nullptr;
        }
    }
    //赋值运算符函数
    String & operator=(const String & rhs){
        if(this != &rhs){
            //判断左操作数
            if(_size <= 15){
                memset(_buffer._arr,0,sizeof(_buffer._arr));
            }else{
                delete [] _buffer._pstr;
            }
            //判断右操作数
            if(rhs._size <= 15){
                strcpy(_buffer._arr,rhs._buffer._arr);
            }else{
                _buffer._pstr = new char [strlen(rhs._buffer._pstr)+1]();
                strcpy(_buffer._pstr,rhs._buffer._pstr);
            }
        }         
        return *this;
    }

    const char * c_str() const{
        if(_size <= 15){
            return _buffer._arr;
        }
        return _buffer._pstr;
    }

    friend ostream &operator<<(ostream & os,const String &rhs);

private:
    union Buffer{
        char *_pstr;
        char _arr[16];
    };
    int _size;
    Buffer _buffer;
};

ostream &operator<<(ostream & os,const String &rhs){
    if(rhs._size <= 15){
        os << rhs._buffer._arr;
    }else{
        os << rhs._buffer._pstr;
    }
    return os;
}

void test(){
    String s1;
    String s2("hello,world");
    String s3("hello,world,hello,c+++++++");
    cout << s1 << ":" << &s1 << endl;
    cout << s2 << ":" << &s2 <<  endl;
    cout << s3 << ":" << &s3 <<  endl;
    cout << (void *)s1.c_str() << endl;
    cout << (void *)s2.c_str() << endl;
    cout << (void *)s3.c_str() << endl;
    String s4 = s3;
    cout << s4 << ":" << &s4 << endl;
}

int main()
{
    test();
    return 0;
}

